> On 10 Feb 2023, at 17:53, Visa Hankala <v...@hankala.org> wrote:
> 
> This makes log event filter MP-safe.
> 
> OK?
> 

ok mvs@

> Index: kern/subr_log.c
> ===================================================================
> RCS file: src/sys/kern/subr_log.c,v
> retrieving revision 1.75
> diff -u -p -r1.75 subr_log.c
> --- kern/subr_log.c   2 Jul 2022 08:50:42 -0000       1.75
> +++ kern/subr_log.c   10 Feb 2023 14:44:20 -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;         /* [L] list of knotes */
>       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,17 +100,22 @@ struct   mutex log_mtx =
> 
> void filt_logrdetach(struct knote *kn);
> int filt_logread(struct knote *kn, long hint);
> +int filt_logmodify(struct kevent *kev, struct knote *kn);
> +int filt_logprocess(struct knote *kn, struct kevent *kev);
> 
> 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);
> void logtick(void *);
> size_t msgbuf_getlen(struct msgbuf *);
> +size_t msgbuf_getlen_locked(struct msgbuf *);
> void msgbuf_putchar_locked(struct msgbuf *, const char);
> 
> void
> @@ -189,13 +195,22 @@ msgbuf_putchar_locked(struct msgbuf *mbp
> size_t
> msgbuf_getlen(struct msgbuf *mbp)
> {
> -     long len;
> +     size_t len;
> 
>       mtx_enter(&log_mtx);
> +     len = msgbuf_getlen_locked(mbp);
> +     mtx_leave(&log_mtx);
> +     return (len);
> +}
> +
> +size_t
> +msgbuf_getlen_locked(struct msgbuf *mbp)
> +{
> +     long len;
> +
>       len = mbp->msg_bufx - mbp->msg_bufr;
>       if (len < 0)
>               len += mbp->msg_bufs;
> -     mtx_leave(&log_mtx);
>       return (len);
> }
> 
> @@ -205,6 +220,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);
> @@ -227,6 +243,7 @@ logclose(dev_t dev, int flag, int mode, 
>       timeout_del(&logsoftc.sc_tick);
>       logsoftc.sc_state = 0;
>       sigio_free(&logsoftc.sc_sigio);
> +     klist_free(&logsoftc.sc_klist);
>       return (0);
> }
> 
> @@ -302,11 +319,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:
> @@ -315,9 +331,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);
> }
> @@ -325,11 +339,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
> @@ -337,10 +347,36 @@ filt_logread(struct knote *kn, long hint
> {
>       struct msgbuf *mbp = kn->kn_hook;
> 
> -     kn->kn_data = msgbuf_getlen(mbp);
> +     MUTEX_ASSERT_LOCKED(&log_mtx);
> +
> +     kn->kn_data = msgbuf_getlen_locked(mbp);
>       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)
> {
> @@ -381,9 +417,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)
> 

Reply via email to