> On 10 Feb 2023, at 17:53, Visa Hankala <[email protected]> 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)
>