On Thu, Sep 14, 2023 at 01:12:22PM +0300, Vitaliy Makkoveev wrote: > `log_mtx' mutex(9) already used for message buffer protection, so use it > to protect `logread_filtops' too. > > ok?
OK bluhm@ > Index: sys/kern/subr_log.c > =================================================================== > RCS file: /cvs/src/sys/kern/subr_log.c,v > retrieving revision 1.77 > diff -u -p -r1.77 subr_log.c > --- sys/kern/subr_log.c 14 Jul 2023 07:07:08 -0000 1.77 > +++ sys/kern/subr_log.c 14 Sep 2023 10:04:41 -0000 > @@ -50,6 +50,7 @@ > #include <sys/filedesc.h> > #include <sys/socket.h> > #include <sys/socketvar.h> > +#include <sys/event.h> > #include <sys/fcntl.h> > #include <sys/mutex.h> > #include <sys/timeout.h> > @@ -75,7 +76,7 @@ > */ > struct logsoftc { > int sc_state; /* [L] see above for possibilities */ > - struct selinfo sc_selp; /* process waiting on select call */ > + struct klist sc_klist; /* process waiting on kevent call */ > struct sigio_ref sc_sigio; /* async I/O registration */ > int sc_need_wakeup; /* if set, wake up waiters */ > struct timeout sc_tick; /* wakeup poll timeout */ > @@ -99,12 +100,16 @@ struct mutex log_mtx = > > void filt_logrdetach(struct knote *kn); > int filt_logread(struct knote *kn, long hint); > +int filt_logmodify(struct kevent *, struct knote *); > +int filt_logprocess(struct knote *, struct kevent *); > > const struct filterops logread_filtops = { > - .f_flags = FILTEROP_ISFD, > + .f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE, > .f_attach = NULL, > .f_detach = filt_logrdetach, > .f_event = filt_logread, > + .f_modify = filt_logmodify, > + .f_process = filt_logprocess, > }; > > int dosendsyslog(struct proc *, const char *, size_t, int, enum uio_seg); > @@ -191,11 +196,9 @@ msgbuf_getlen(struct msgbuf *mbp) > { > long len; > > - mtx_enter(&log_mtx); > len = mbp->msg_bufx - mbp->msg_bufr; > if (len < 0) > len += mbp->msg_bufs; > - mtx_leave(&log_mtx); > return (len); > } > > @@ -205,6 +208,7 @@ logopen(dev_t dev, int flags, int mode, > if (log_open) > return (EBUSY); > log_open = 1; > + klist_init_mutex(&logsoftc.sc_klist, &log_mtx); > sigio_init(&logsoftc.sc_sigio); > timeout_set(&logsoftc.sc_tick, logtick, NULL); > timeout_add_msec(&logsoftc.sc_tick, LOG_TICK); > @@ -225,6 +229,10 @@ logclose(dev_t dev, int flag, int mode, > FRELE(fp, p); > log_open = 0; > timeout_del(&logsoftc.sc_tick); > + > + klist_invalidate(&logsoftc.sc_klist); > + klist_free(&logsoftc.sc_klist); > + > logsoftc.sc_state = 0; > sigio_free(&logsoftc.sc_sigio); > return (0); > @@ -301,11 +309,10 @@ int > logkqfilter(dev_t dev, struct knote *kn) > { > struct klist *klist; > - int s; > > switch (kn->kn_filter) { > case EVFILT_READ: > - klist = &logsoftc.sc_selp.si_note; > + klist = &logsoftc.sc_klist; > kn->kn_fop = &logread_filtops; > break; > default: > @@ -313,10 +320,7 @@ logkqfilter(dev_t dev, struct knote *kn) > } > > kn->kn_hook = (void *)msgbufp; > - > - s = splhigh(); > - klist_insert_locked(klist, kn); > - splx(s); > + klist_insert(klist, kn); > > return (0); > } > @@ -324,11 +328,7 @@ logkqfilter(dev_t dev, struct knote *kn) > void > filt_logrdetach(struct knote *kn) > { > - int s; > - > - s = splhigh(); > - klist_remove_locked(&logsoftc.sc_selp.si_note, kn); > - splx(s); > + klist_remove(&logsoftc.sc_klist, kn); > } > > int > @@ -340,6 +340,30 @@ filt_logread(struct knote *kn, long hint > return (kn->kn_data != 0); > } > > +int > +filt_logmodify(struct kevent *kev, struct knote *kn) > +{ > + int active; > + > + mtx_enter(&log_mtx); > + active = knote_modify(kev, kn); > + mtx_leave(&log_mtx); > + > + return (active); > +} > + > +int > +filt_logprocess(struct knote *kn, struct kevent *kev) > +{ > + int active; > + > + mtx_enter(&log_mtx); > + active = knote_process(kn, kev); > + mtx_leave(&log_mtx); > + > + return (active); > +} > + > void > logwakeup(void) > { > @@ -380,9 +404,9 @@ logtick(void *arg) > state = logsoftc.sc_state; > if (logsoftc.sc_state & LOG_RDWAIT) > logsoftc.sc_state &= ~LOG_RDWAIT; > + knote_locked(&logsoftc.sc_klist, 0); > mtx_leave(&log_mtx); > > - selwakeup(&logsoftc.sc_selp); > if (state & LOG_ASYNC) > pgsigio(&logsoftc.sc_sigio, SIGIO, 0); > if (state & LOG_RDWAIT) > @@ -401,7 +425,9 @@ logioctl(dev_t dev, u_long com, caddr_t > > /* return number of characters immediately available */ > case FIONREAD: > + mtx_enter(&log_mtx); > *(int *)data = (int)msgbuf_getlen(msgbufp); > + mtx_leave(&log_mtx); > break; > > case FIONBIO: