kernel - Make filters able to be marked MPSAFE
authorSamuel J. Greear <sjg@thesjg.com>
Tue, 3 Aug 2010 15:11:21 +0000 (15:11 +0000)
committerSamuel J. Greear <sjg@thesjg.com>
Tue, 3 Aug 2010 17:44:29 +0000 (17:44 +0000)
* Change struct filterops f_isfd field to f_flags, taking FILTEROP_ISFD and/or
  FILTEROP_MPSAFE.

* Convert all existing filter definitions to use new flags.

* Create filter_attach/detach/event wrapper functions for calling through the
  struct filterops vector that grab the MPLOCK as necessary.

* kern_event() uses kq->kq_count to determine whether or not to sleep,
  kqueue_scan() removes events from the TAILQ and can possibly sleep, releasing
  the global kq token, before updating kq->kq_count.

50 files changed:
sys/bus/cam/scsi/scsi_target.c
sys/bus/firewire/fwdev.c
sys/bus/usb/usb.c
sys/dev/drm/drm_fops.c
sys/dev/misc/cmx/cmx.c
sys/dev/misc/hotplug/hotplug.c
sys/dev/misc/kbd/kbd.c
sys/dev/misc/mse/mse.c
sys/dev/misc/psm/psm.c
sys/dev/misc/snp/snp.c
sys/dev/misc/spic/spic.c
sys/dev/misc/tw/tw.c
sys/dev/raid/aac/aac.c
sys/dev/raid/vinum/vinum.c
sys/dev/sound/pcm/dsp.c
sys/dev/usbmisc/ugen/ugen.c
sys/dev/usbmisc/uhid/uhid.c
sys/dev/usbmisc/ums/ums.c
sys/dev/usbmisc/uscanner/uscanner.c
sys/dev/video/bktr/bktr_os.c
sys/dev/video/cxm/cxm.c
sys/kern/kern_event.c
sys/kern/kern_memio.c
sys/kern/kern_sig.c
sys/kern/kern_udev.c
sys/kern/subr_bus.c
sys/kern/subr_log.c
sys/kern/sys_mqueue.c
sys/kern/sys_pipe.c
sys/kern/tty.c
sys/kern/tty_pty.c
sys/kern/tty_tty.c
sys/kern/uipc_socket.c
sys/net/bpf.c
sys/net/i4b/driver/i4b_rbch.c
sys/net/i4b/driver/i4b_tel.c
sys/net/i4b/layer4/i4b_i4bdrv.c
sys/net/tap/if_tap.c
sys/net/tun/if_tun.c
sys/platform/pc32/acpica5/acpi_machdep.c
sys/platform/pc32/apm/apm.c
sys/platform/pc32/isa/asc.c
sys/platform/pc64/acpica5/acpi_machdep.c
sys/platform/pc64/apm/apm.c
sys/platform/pc64/isa/asc.c
sys/sys/event.h
sys/vfs/fifofs/fifo_vnops.c
sys/vfs/gnu/ext2fs/ext2_vnops.c
sys/vfs/hammer/hammer_vnops.c
sys/vfs/ufs/ufs_vnops.c

index 5993da7..6156d46 100644 (file)
@@ -105,9 +105,9 @@ static void         targfiltdetach(struct knote *kn);
 static int             targreadfilt(struct knote *kn, long hint);
 static int             targwritefilt(struct knote *kn, long hint);
 static struct filterops targread_filtops =
-       { 1, NULL, targfiltdetach, targreadfilt };
+       { FILTEROP_ISFD, NULL, targfiltdetach, targreadfilt };
 static struct filterops targwrite_filtops =
-       { 1, NULL, targfiltdetach, targwritefilt };
+       { FILTEROP_ISFD, NULL, targfiltdetach, targwritefilt };
 
 #define TARG_CDEV_MAJOR 65
 static struct dev_ops targ_ops = {
index 5acb9c3..3aace2a 100644 (file)
@@ -714,9 +714,9 @@ out:
 }
 
 static struct filterops fw_read_filterops =
-       { 1, NULL, fwfilt_detach, fwfilt_read };
+       { FILTEROP_ISFD, NULL, fwfilt_detach, fwfilt_read };
 static struct filterops fw_write_filterops =
-       { 1, NULL, fwfilt_detach, fwfilt_write };
+       { FILTEROP_ISFD, NULL, fwfilt_detach, fwfilt_write };
 
 static int
 fw_kqfilter(struct dev_kqfilter_args *ap)
index 04cd553..fec9f72 100644 (file)
@@ -696,7 +696,7 @@ usbioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops usbfiltops =
-       { 1, NULL, usbfilt_detach, usbfilt };
+       { FILTEROP_ISFD, NULL, usbfilt_detach, usbfilt };
 
 int
 usbkqfilter(struct dev_kqfilter_args *ap)
index af87270..ae4a9e2 100644 (file)
@@ -119,7 +119,7 @@ static void
 drmfilt_detach(struct knote *kn) {}
 
 static struct filterops drmfiltops =
-        { 1, NULL, drmfilt_detach, drmfilt };
+        { FILTEROP_ISFD, NULL, drmfilt_detach, drmfilt };
 
 int
 drm_kqfilter(struct dev_kqfilter_args *ap)
index 5f62dc0..bf19362 100644 (file)
@@ -646,9 +646,9 @@ cmx_write(struct dev_write_args *ap)
 }
 
 static struct filterops cmx_read_filterops =
-       { 1, NULL, cmx_filter_detach, cmx_filter_read };
+       { FILTEROP_ISFD, NULL, cmx_filter_detach, cmx_filter_read };
 static struct filterops cmx_write_filterops =
-       { 1, NULL, cmx_filter_detach, cmx_filter_write };
+       { FILTEROP_ISFD, NULL, cmx_filter_detach, cmx_filter_write };
 
 /*
  * Kevent handler.  Writing is always possible, reading is only possible
index 0417cef..5bda728 100644 (file)
@@ -104,7 +104,7 @@ hotplugclose(struct dev_close_args *ap)
 }
 
 static struct filterops hotplugfiltops =
-       { 1, NULL, hotplugfiltdetach, hotplugfilt };
+       { FILTEROP_ISFD, NULL, hotplugfiltdetach, hotplugfilt };
 
 static int
 hotplugkqfilter(struct dev_kqfilter_args *ap)
index 0f51936..bf940e6 100644 (file)
@@ -746,7 +746,7 @@ genkbdioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops genkbdfiltops =
-       { 1, NULL, genkbdfiltdetach, genkbdfilter };
+       { FILTEROP_ISFD, NULL, genkbdfiltdetach, genkbdfilter };
 
 static int
 genkbdkqfilter(struct dev_kqfilter_args *ap)
index 2ed49ca..abd5c2d 100644 (file)
@@ -608,7 +608,7 @@ mseioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops msefiltops =
-       { 1, NULL, msefilter_detach, msefilter };
+       { FILTEROP_ISFD, NULL, msefilter_detach, msefilter };
 
 static int
 msekqfilter(struct dev_kqfilter_args *ap)
index 1911c77..6af8d4e 100644 (file)
@@ -2379,7 +2379,7 @@ psmintr(void *arg)
 }
 
 static struct filterops psmfiltops =
-       { 1, NULL, psmfilter_detach, psmfilter };
+       { FILTEROP_ISFD, NULL, psmfilter_detach, psmfilter };
 
 static int
 psmkqfilter(struct dev_kqfilter_args *ap)
index 3999707..ffd425d 100644 (file)
@@ -561,9 +561,9 @@ snpioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops snpfiltops_rd =
-        { 1, NULL, snpfilter_detach, snpfilter_rd };
+        { FILTEROP_ISFD, NULL, snpfilter_detach, snpfilter_rd };
 static struct filterops snpfiltops_wr =
-        { 1, NULL, snpfilter_detach, snpfilter_wr };
+        { FILTEROP_ISFD, NULL, snpfilter_detach, snpfilter_wr };
 
 static int
 snpkqfilter(struct dev_kqfilter_args *ap)
index 370c554..336ebe7 100644 (file)
@@ -522,7 +522,7 @@ spicioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops spicfiltops =
-       { 1, NULL, spicfilt_detach, spicfilt };
+       { FILTEROP_ISFD, NULL, spicfilt_detach, spicfilt };
 
 static int
 spickqfilter(struct dev_kqfilter_args *ap)
index 201cc24..ac2e31c 100644 (file)
@@ -525,9 +525,9 @@ twwrite(struct dev_write_args *ap)
  */
 
 static struct filterops twfiltops_read =
-       { 1, NULL, twfilter_detach, twfilter_read };
+       { FILTEROP_ISFD, NULL, twfilter_detach, twfilter_read };
 static struct filterops twfiltops_write =
-       { 1, NULL, twfilter_detach, twfilter_write };
+       { FILTEROP_ISFD, NULL, twfilter_detach, twfilter_write };
 
 static int
 twkqfilter(struct dev_kqfilter_args *ap)
index cfc8f0c..f8a850f 100644 (file)
@@ -3062,7 +3062,7 @@ aac_ioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops aac_filterops =
-       { 1, NULL, aac_filter_detach, aac_filter };
+       { FILTEROP_ISFD, NULL, aac_filter_detach, aac_filter };
 
 static int
 aac_kqfilter(struct dev_kqfilter_args *ap)
index 9b9c540..20cfdeb 100644 (file)
@@ -599,9 +599,9 @@ vinumfilt_wr(struct knote *kn, long hint)
 }
 
 struct filterops vinumfiltops_rd =
-    { 1, NULL, vinumfilt_detach, vinumfilt_rd };
+    { FILTEROP_ISFD, NULL, vinumfilt_detach, vinumfilt_rd };
 struct filterops vinumfiltops_wr =
-    { 1, NULL, vinumfilt_detach, vinumfilt_wr };
+    { FILTEROP_ISFD, NULL, vinumfilt_detach, vinumfilt_wr };
 
 int
 vinumkqfilter(struct dev_kqfilter_args *ap)
index a56ae39..e09e6a7 100644 (file)
@@ -1087,9 +1087,9 @@ dsp_ioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops dsp_read_filtops =
-       { 1, NULL, dsp_filter_detach, dsp_filter_read };
+       { FILTEROP_ISFD, NULL, dsp_filter_detach, dsp_filter_read };
 static struct filterops dsp_write_filtops =
-       { 1, NULL, dsp_filter_detach, dsp_filter_write };
+       { FILTEROP_ISFD, NULL, dsp_filter_detach, dsp_filter_write };
 
 static int
 dsp_kqfilter(struct dev_kqfilter_args *ap)
index aa7e456..425dd1e 100644 (file)
@@ -1426,9 +1426,9 @@ ugenioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops ugen_filtops_read =
-       { 1, NULL, ugen_filt_detach, ugen_filt_read };
+       { FILTEROP_ISFD, NULL, ugen_filt_detach, ugen_filt_read };
 static struct filterops ugen_filtops_write =
-       { 1, NULL, ugen_filt_detach, ugen_filt_write };
+       { FILTEROP_ISFD, NULL, ugen_filt_detach, ugen_filt_write };
 
 int
 ugenkqfilter(struct dev_kqfilter_args *ap)
index 579f3b7..bd9693a 100644 (file)
@@ -669,9 +669,9 @@ uhidioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops uhidfiltops_read =
-       { 1, NULL, uhidfilt_detach, uhidfilt_read };
+       { FILTEROP_ISFD, NULL, uhidfilt_detach, uhidfilt_read };
 static struct filterops uhidfiltops_write =
-       { 1, NULL, uhidfilt_detach, uhidfilt_write };
+       { FILTEROP_ISFD, NULL, uhidfilt_detach, uhidfilt_write };
 
 int
 uhidkqfilter(struct dev_kqfilter_args *ap)
index c770597..bfec24d 100644 (file)
@@ -666,7 +666,7 @@ ums_read(struct dev_read_args *ap)
 }
 
 static struct filterops ums_filtops =
-       { 1, NULL, ums_filt_detach, ums_filt };
+       { FILTEROP_ISFD, NULL, ums_filt_detach, ums_filt };
 
 static int
 ums_kqfilter(struct dev_kqfilter_args *ap)
index 0901ae6..2981b12 100644 (file)
@@ -660,7 +660,7 @@ uscannerfilt(struct knote *kn, long hint)
 }
 
 static struct filterops uscannerfiltops =
-       { 1, NULL, uscannerfilt_detach, uscannerfilt };
+       { FILTEROP_ISFD, NULL, uscannerfilt_detach, uscannerfilt };
 
 int
 uscannerkqfilter(struct dev_kqfilter_args *ap)
index 35c1fa7..e5e05b6 100644 (file)
@@ -720,7 +720,7 @@ bktr_mmap(struct dev_mmap_args *ap)
 }
 
 static struct filterops bktr_filterops =
-       { 1, NULL, bktr_filter_detach, bktr_filter };
+       { FILTEROP_ISFD, NULL, bktr_filter_detach, bktr_filter };
 
 static int
 bktr_kqfilter(struct dev_kqfilter_args *ap)
index c596452..a66e756 100644 (file)
@@ -2907,7 +2907,7 @@ cxm_ioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops cxm_filterops =
-       { 1, NULL, cxm_filter_detach, cxm_filter };
+       { FILTEROP_ISFD, NULL, cxm_filter_detach, cxm_filter };
 
 static int
 cxm_kqfilter(struct dev_kqfilter_args *ap)
index 85d9ace..65ff246 100644 (file)
@@ -83,6 +83,9 @@ static int    kqueue_stat(struct file *fp, struct stat *st,
                    struct ucred *cred);
 static int     kqueue_close(struct file *fp);
 static void    kqueue_wakeup(struct kqueue *kq);
+static int     filter_attach(struct knote *kn);
+static void    filter_detach(struct knote *kn);
+static int     filter_event(struct knote *kn, long hint);
 
 /*
  * MPSAFE
@@ -117,9 +120,9 @@ static void filt_timerdetach(struct knote *kn);
 static int     filt_timer(struct knote *kn, long hint);
 
 static struct filterops file_filtops =
-       { 1, filt_fileattach, NULL, NULL };
+       { FILTEROP_ISFD, filt_fileattach, NULL, NULL };
 static struct filterops kqread_filtops =
-       { 1, NULL, filt_kqdetach, filt_kqueue };
+       { FILTEROP_ISFD, NULL, filt_kqdetach, filt_kqueue };
 static struct filterops proc_filtops =
        { 0, filt_procattach, filt_procdetach, filt_proc };
 static struct filterops timer_filtops =
@@ -419,8 +422,8 @@ kqueue_terminate(struct kqueue *kq)
        int hv;
 
        while ((kn = TAILQ_FIRST(&kq->kq_knlist)) != NULL) {
-               kn->kn_fop->f_detach(kn);
-               if (kn->kn_fop->f_isfd) {
+               filter_detach(kn);
+               if (kn->kn_fop->f_flags & FILTEROP_ISFD) {
                        list = &kn->kn_fp->f_klist;
                        SLIST_REMOVE(list, kn, knote, kn_link);
                        fdrop(kn->kn_fp);
@@ -746,7 +749,7 @@ kqueue_register(struct kqueue *kq, struct kevent *kev)
                return (EINVAL);
        }
 
-       if (fops->f_isfd) {
+       if (fops->f_flags & FILTEROP_ISFD) {
                /* validate descriptor */
                fp = holdfp(fdp, kev->ident, -1);
                if (fp == NULL)
@@ -805,7 +808,7 @@ kqueue_register(struct kqueue *kq, struct kevent *kev)
                        kn->kn_kevent = *kev;
 
                        knote_attach(kn);
-                       if ((error = fops->f_attach(kn)) != 0) {
+                       if ((error = filter_attach(kn)) != 0) {
                                knote_drop(kn);
                                goto done;
                        }
@@ -820,10 +823,11 @@ kqueue_register(struct kqueue *kq, struct kevent *kev)
                        kn->kn_kevent.udata = kev->udata;
                }
 
-               if (kn->kn_fop->f_event(kn, 0))
+               if (filter_event(kn, 0))
                        KNOTE_ACTIVATE(kn);
+
        } else if (kev->flags & EV_DELETE) {
-               kn->kn_fop->f_detach(kn);
+               filter_detach(kn);
                knote_drop(kn);
                goto done;
        }
@@ -921,15 +925,14 @@ kqueue_scan(struct kqueue *kq, struct kevent *kevp, int count,
                }
 
                TAILQ_REMOVE(&kq->kq_knpend, kn, kn_tqe);
+               kq->kq_count--;
                if (kn->kn_status & KN_DISABLED) {
                        kn->kn_status &= ~KN_QUEUED;
-                       kq->kq_count--;
                        continue;
                }
                if ((kn->kn_flags & EV_ONESHOT) == 0 &&
-                   kn->kn_fop->f_event(kn, 0) == 0) {
+                   filter_event(kn, 0) == 0) {
                        kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE);
-                       kq->kq_count--;
                        continue;
                }
                *kevp++ = kn->kn_kevent;
@@ -941,16 +944,15 @@ kqueue_scan(struct kqueue *kq, struct kevent *kevp, int count,
                 */
                if (kn->kn_flags & EV_ONESHOT) {
                        kn->kn_status &= ~KN_QUEUED;
-                       kq->kq_count--;
-                       kn->kn_fop->f_detach(kn);
+                       filter_detach(kn);
                        knote_drop(kn);
                } else if (kn->kn_flags & EV_CLEAR) {
                        kn->kn_data = 0;
                        kn->kn_fflags = 0;
                        kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE);
-                       kq->kq_count--;
                } else {
                        TAILQ_INSERT_TAIL(&kq->kq_knpend, kn, kn_tqe);
+                       kq->kq_count++;
                }
        }
        TAILQ_REMOVE(&kq->kq_knpend, &local_marker, kn_tqe);
@@ -1056,6 +1058,62 @@ kqueue_wakeup(struct kqueue *kq)
        KNOTE(&kq->kq_kqinfo.ki_note, 0);
 }
 
+/*
+ * Calls filterops f_attach function, acquiring mplock if filter is not
+ * marked as FILTEROP_MPSAFE.
+ */
+static int
+filter_attach(struct knote *kn)
+{
+       int ret;
+
+       if (!(kn->kn_fop->f_flags & FILTEROP_MPSAFE)) {
+               get_mplock();
+               ret = kn->kn_fop->f_attach(kn);
+               rel_mplock();
+       } else {
+               ret = kn->kn_fop->f_attach(kn);
+       }
+
+       return (ret);
+}
+
+/*
+ * Calls filterops f_detach function, acquiring mplock if filter is not
+ * marked as FILTEROP_MPSAFE.
+ */
+static void
+filter_detach(struct knote *kn)
+{
+       if (!(kn->kn_fop->f_flags & FILTEROP_MPSAFE)) {
+               get_mplock();
+               kn->kn_fop->f_detach(kn);
+               rel_mplock();
+       } else {
+               kn->kn_fop->f_detach(kn);
+       }
+}
+
+/*
+ * Calls filterops f_event function, acquiring mplock if filter is not
+ * marked as FILTEROP_MPSAFE.
+ */
+static int
+filter_event(struct knote *kn, long hint)
+{
+       int ret;
+
+       if (!(kn->kn_fop->f_flags & FILTEROP_MPSAFE)) {
+               get_mplock();
+               ret = kn->kn_fop->f_event(kn, hint);
+               rel_mplock();
+       } else {
+               ret = kn->kn_fop->f_event(kn, hint);
+       }
+
+       return (ret);
+}
+
 /*
  * walk down a list of knotes, activating them if their event has triggered.
  */
@@ -1066,7 +1124,7 @@ knote(struct klist *list, long hint)
 
        lwkt_gettoken(&kq_token);
        SLIST_FOREACH(kn, list, kn_next)
-               if (kn->kn_fop->f_event(kn, hint))
+               if (filter_event(kn, hint))
                        KNOTE_ACTIVATE(kn);
        lwkt_reltoken(&kq_token);
 }
@@ -1103,7 +1161,7 @@ knote_empty(struct klist *list)
 
        lwkt_gettoken(&kq_token);
        while ((kn = SLIST_FIRST(list)) != NULL) {
-               kn->kn_fop->f_detach(kn);
+               filter_detach(kn);
                knote_drop(kn);
        }
        lwkt_reltoken(&kq_token);
@@ -1121,7 +1179,7 @@ knote_fdclose(struct file *fp, struct filedesc *fdp, int fd)
 restart:
        SLIST_FOREACH(kn, &fp->f_klist, kn_link) {
                if (kn->kn_kq->kq_fdp == fdp && kn->kn_id == fd) {
-                       kn->kn_fop->f_detach(kn);
+                       filter_detach(kn);
                        knote_drop(kn);
                        goto restart;
                }
@@ -1135,7 +1193,7 @@ knote_attach(struct knote *kn)
        struct klist *list;
        struct kqueue *kq = kn->kn_kq;
 
-       if (kn->kn_fop->f_isfd) {
+       if (kn->kn_fop->f_flags & FILTEROP_ISFD) {
                KKASSERT(kn->kn_fp);
                list = &kn->kn_fp->f_klist;
        } else {
@@ -1157,7 +1215,7 @@ knote_drop(struct knote *kn)
 
        kq = kn->kn_kq;
 
-       if (kn->kn_fop->f_isfd)
+       if (kn->kn_fop->f_flags & FILTEROP_ISFD)
                list = &kn->kn_fp->f_klist;
        else
                list = &kq->kq_knhash[KN_HASH(kn->kn_id, kq->kq_knhashmask)];
@@ -1166,7 +1224,7 @@ knote_drop(struct knote *kn)
        TAILQ_REMOVE(&kq->kq_knlist, kn, kn_kqlink);
        if (kn->kn_status & KN_QUEUED)
                knote_dequeue(kn);
-       if (kn->kn_fop->f_isfd)
+       if (kn->kn_fop->f_flags & FILTEROP_ISFD)
                fdrop(kn->kn_fp);
        knote_free(kn);
 }
index 9c76b8a..bb32304 100644 (file)
@@ -537,10 +537,10 @@ static void
 dummy_filter_detach(struct knote *kn) {}
 
 static struct filterops random_read_filtops =
-        { 1, NULL, dummy_filter_detach, random_filter_read };
+        { FILTEROP_ISFD, NULL, dummy_filter_detach, random_filter_read };
 
 static struct filterops mm_read_filtops =
-        { 1, NULL, dummy_filter_detach, mm_filter_read };
+        { FILTEROP_ISFD, NULL, dummy_filter_detach, mm_filter_read };
 
 int
 mmkqfilter(struct dev_kqfilter_args *ap)
index eb69126..9c4ad84 100644 (file)
@@ -92,7 +92,7 @@ static void   filt_sigdetach(struct knote *kn);
 static int     filt_signal(struct knote *kn, long hint);
 
 struct filterops sig_filtops =
-       { 0, filt_sigattach, filt_sigdetach, filt_signal };
+       { FILTEROP_ISFD, filt_sigattach, filt_sigdetach, filt_signal };
 
 static int     kern_logsigexit = 1;
 SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW, 
index e00b574..8b918f1 100644 (file)
@@ -577,7 +577,7 @@ udev_dev_close(struct dev_close_args *ap)
 }
 
 static struct filterops udev_dev_read_filtops =
-       { 1, NULL, udev_dev_filter_detach, udev_dev_filter_read };
+       { FILTEROP_ISFD, NULL, udev_dev_filter_detach, udev_dev_filter_read };
 
 static int
 udev_dev_kqfilter(struct dev_kqfilter_args *ap)
index efc5aa4..26972e6 100644 (file)
@@ -277,7 +277,7 @@ static void dev_filter_detach(struct knote *);
 static int dev_filter_read(struct knote *, long);
 
 static struct filterops dev_filtops =
-       { 1, NULL, dev_filter_detach, dev_filter_read };
+       { FILTEROP_ISFD, NULL, dev_filter_detach, dev_filter_read };
 
 static int
 devkqfilter(struct dev_kqfilter_args *ap)
index bc89aec..6926e44 100644 (file)
@@ -163,7 +163,7 @@ logread(struct dev_read_args *ap)
 }
 
 static struct filterops logread_filtops =
-       { 1, NULL, logfiltdetach, logfiltread };
+       { FILTEROP_ISFD, NULL, logfiltdetach, logfiltread };
 
 static int
 logkqfilter(struct dev_kqfilter_args *ap)
index 47d9a85..09686ba 100644 (file)
@@ -316,9 +316,9 @@ mq_stat_fop(file_t *fp, struct stat *st, struct ucred *cred)
 }
 
 static struct filterops mqfiltops_read =
-       { 1, NULL, mqfilter_read_detach, mqfilter_read };
+       { FILTEROP_ISFD, NULL, mqfilter_read_detach, mqfilter_read };
 static struct filterops mqfiltops_write =
-       { 1, NULL, mqfilter_write_detach, mqfilter_write };
+       { FILTEROP_ISFD, NULL, mqfilter_write_detach, mqfilter_write };
 
 static int
 mq_kqfilter_fop(struct file *fp, struct knote *kn)
index 3a1e446..3efc664 100644 (file)
@@ -94,9 +94,9 @@ static int    filt_piperead(struct knote *kn, long hint);
 static int     filt_pipewrite(struct knote *kn, long hint);
 
 static struct filterops pipe_rfiltops =
-       { 1, NULL, filt_pipedetach, filt_piperead };
+       { FILTEROP_ISFD, NULL, filt_pipedetach, filt_piperead };
 static struct filterops pipe_wfiltops =
-       { 1, NULL, filt_pipedetach, filt_pipewrite };
+       { FILTEROP_ISFD, NULL, filt_pipedetach, filt_pipewrite };
 
 MALLOC_DEFINE(M_PIPE, "pipe", "pipe structures");
 
index 6a40730..6c24a89 100644 (file)
@@ -1157,9 +1157,9 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
 }
 
 static struct filterops ttyread_filtops =
-       { 1, NULL, filt_ttyrdetach, filt_ttyread };
+       { FILTEROP_ISFD, NULL, filt_ttyrdetach, filt_ttyread };
 static struct filterops ttywrite_filtops =
-       { 1, NULL, filt_ttywdetach, filt_ttywrite };
+       { FILTEROP_ISFD, NULL, filt_ttywdetach, filt_ttywrite };
 
 int
 ttykqfilter(struct dev_kqfilter_args *ap)
index 5a9d238..b21907f 100644 (file)
@@ -651,9 +651,9 @@ ptsstop(struct tty *tp, int flush)
  * kqueue ops for pseudo-terminals.
  */
 static struct filterops ptcread_filtops =
-       { 1, NULL, filt_ptcrdetach, filt_ptcread };
+       { FILTEROP_ISFD, NULL, filt_ptcrdetach, filt_ptcread };
 static struct filterops ptcwrite_filtops =
-       { 1, NULL, filt_ptcwdetach, filt_ptcwrite };
+       { FILTEROP_ISFD, NULL, filt_ptcwdetach, filt_ptcwrite };
 
 static int
 ptckqfilter(struct dev_kqfilter_args *ap)
index ed28148..edfe21c 100644 (file)
@@ -241,9 +241,9 @@ cttyioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops cttyfiltops_read =
-       { 1, NULL, cttyfilt_detach, cttyfilt_read };
+       { FILTEROP_ISFD, NULL, cttyfilt_detach, cttyfilt_read };
 static struct filterops cttyfiltops_write =
-       { 1, NULL, cttyfilt_detach, cttyfilt_write };
+       { FILTEROP_ISFD, NULL, cttyfilt_detach, cttyfilt_write };
 
 static int
 cttykqfilter(struct dev_kqfilter_args *ap)
index 8dea80e..39f19ac 100644 (file)
@@ -110,13 +110,13 @@ static int        filt_sowrite(struct knote *kn, long hint);
 static int     filt_solisten(struct knote *kn, long hint);
 
 static struct filterops solisten_filtops = 
-       { 1, NULL, filt_sordetach, filt_solisten };
+       { FILTEROP_ISFD, NULL, filt_sordetach, filt_solisten };
 static struct filterops soread_filtops =
-       { 1, NULL, filt_sordetach, filt_soread };
+       { FILTEROP_ISFD, NULL, filt_sordetach, filt_soread };
 static struct filterops sowrite_filtops = 
-       { 1, NULL, filt_sowdetach, filt_sowrite };
+       { FILTEROP_ISFD, NULL, filt_sowdetach, filt_sowrite };
 static struct filterops soexcept_filtops =
-       { 1, NULL, filt_sordetach, filt_soread };
+       { FILTEROP_ISFD, NULL, filt_sordetach, filt_soread };
 
 MALLOC_DEFINE(M_SOCKET, "socket", "socket struct");
 MALLOC_DEFINE(M_SONAME, "soname", "socket name");
index 98a5c65..297e8dc 100644 (file)
@@ -1067,7 +1067,7 @@ bpf_setif(struct bpf_d *d, struct ifreq *ifr)
 }
 
 static struct filterops bpf_read_filtops =
-       { 1, NULL, bpf_filter_detach, bpf_filter_read };
+       { FILTEROP_ISFD, NULL, bpf_filter_detach, bpf_filter_read };
 
 static int
 bpfkqfilter(struct dev_kqfilter_args *ap)
index 31ba6c8..c9373d9 100644 (file)
@@ -532,9 +532,9 @@ i4brbchioctl(struct dev_ioctl_args *ap)
  *     device driver poll
  *---------------------------------------------------------------------------*/
 static struct filterops i4brbchkfiltops_read =
-       { 1, NULL, i4brbchkfilt_detach, i4brbchkfilt_read };
+       { FILTEROP_ISFD, NULL, i4brbchkfilt_detach, i4brbchkfilt_read };
 static struct filterops i4brbchkfiltops_write =
-       { 1, NULL, i4brbchkfilt_detach, i4brbchkfilt_write };
+       { FILTEROP_ISFD, NULL, i4brbchkfilt_detach, i4brbchkfilt_write };
 
 PDEVSTATIC int
 i4brbchkqfilter(struct dev_kqfilter_args *ap)
index 8944d4f..eff20d3 100644 (file)
@@ -686,9 +686,9 @@ tel_tone(tel_sc_t *sc)
  *     device driver poll
  *---------------------------------------------------------------------------*/
 PDEVSTATIC struct filterops i4btelfiltops_read =
-       { 1, NULL, i4btelfilt_detach, i4btelfilt_read };
+       { FILTEROP_ISFD, NULL, i4btelfilt_detach, i4btelfilt_read };
 PDEVSTATIC struct filterops i4btelfiltops_write =
-       { 1, NULL, i4btelfilt_detach, i4btelfilt_write };
+       { FILTEROP_ISFD, NULL, i4btelfilt_detach, i4btelfilt_write };
 
 PDEVSTATIC int
 i4btelkqfilter(struct dev_kqfilter_args *ap)
index e86f826..2b22d64 100644 (file)
@@ -730,9 +730,9 @@ diag_done:
  *     i4bkqfilter - device driver poll routine
  *---------------------------------------------------------------------------*/
 static struct filterops i4bkqfiltops_read =
-       { 1, NULL, i4bkqfilt_detach, i4bkqfilt_read };
+       { FILTEROP_ISFD, NULL, i4bkqfilt_detach, i4bkqfilt_read };
 static struct filterops i4bkqfiltops_write =
-       { 1, NULL, i4bkqfilt_detach, i4bkqfilt_write };
+       { FILTEROP_ISFD, NULL, i4bkqfilt_detach, i4bkqfilt_write };
 
 PDEVSTATIC int
 i4bkqfilter(struct dev_kqfilter_args *ap)
index 67f44a7..8424362 100644 (file)
@@ -938,9 +938,9 @@ static int filt_tapread(struct knote *kn, long hint);
 static int filt_tapwrite(struct knote *kn, long hint);
 static void filt_tapdetach(struct knote *kn);
 static struct filterops tapread_filtops =
-       { 1, NULL, filt_tapdetach, filt_tapread };
+       { FILTEROP_ISFD, NULL, filt_tapdetach, filt_tapread };
 static struct filterops tapwrite_filtops =
-       { 1, NULL, filt_tapdetach, filt_tapwrite };
+       { FILTEROP_ISFD, NULL, filt_tapdetach, filt_tapwrite };
 
 static int
 tapkqfilter(struct dev_kqfilter_args *ap)
index 9076fae..8a87a66 100644 (file)
@@ -700,9 +700,9 @@ tunwrite(struct dev_write_args *ap)
 }
 
 static struct filterops tun_read_filtops =
-       { 1, NULL, tun_filter_detach, tun_filter_read };
+       { FILTEROP_ISFD, NULL, tun_filter_detach, tun_filter_read };
 static struct filterops tun_write_filtops =
-       { 1, NULL, tun_filter_detach, tun_filter_write };
+       { FILTEROP_ISFD, NULL, tun_filter_detach, tun_filter_write };
 
 static int
 tunkqfilter(struct dev_kqfilter_args *ap)
index dba1991..bf2ef13 100644 (file)
@@ -298,7 +298,7 @@ static void apmfilter_detach(struct knote *);
 static int apmfilter(struct knote *, long);
 
 static struct filterops apmfilterops =
-       { 1, NULL, apmfilter_detach, apmfilter };
+       { FILTEROP_ISFD, NULL, apmfilter_detach, apmfilter };
 
 static int
 apmkqfilter(struct dev_kqfilter_args *ap)
index 4ca2d1c..699852f 100644 (file)
@@ -1340,9 +1340,9 @@ apmwrite(struct dev_write_args *ap)
 }
 
 static struct filterops apmfiltops_read =
-       { 1, NULL, apmfilter_detach, apmfilter_read };
+       { FILTEROP_ISFD, NULL, apmfilter_detach, apmfilter_read };
 static struct filterops apmfiltops_write =
-       { 1, NULL, apmfilter_detach, apmfilter_write };
+       { FILTEROP_ISFD, NULL, apmfilter_detach, apmfilter_write };
 
 static int
 apmkqfilter(struct dev_kqfilter_args *ap)
index 2d32642..2ff96f1 100644 (file)
@@ -843,7 +843,7 @@ ascioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops ascfiltops =
-    { 1, NULL, ascfilter_detach, ascfilter };
+    { FILTEROP_ISFD, NULL, ascfilter_detach, ascfilter };
 
 STATIC int
 asckqfilter(struct dev_kqfilter_args *ap)
index f4ce81b..33d2ad6 100644 (file)
@@ -294,7 +294,7 @@ static void apmfilter_detach(struct knote *);
 static int apmfilter(struct knote *, long);
 
 static struct filterops apmfilterops =
-       { 1, NULL, apmfilter_detach, apmfilter };
+       { FILTEROP_ISFD, NULL, apmfilter_detach, apmfilter };
 
 static int
 apmkqfilter(struct dev_kqfilter_args *ap)
index 8cffc61..d636ccc 100644 (file)
@@ -1340,9 +1340,9 @@ apmwrite(struct dev_write_args *ap)
 }
 
 static struct filterops apmfiltops_read =
-       { 1, NULL, apmfilter_detach, apmfilter_read };
+       { FILTEROP_ISFD, NULL, apmfilter_detach, apmfilter_read };
 static struct filterops apmfiltops_write =
-       { 1, NULL, apmfilter_detach, apmfilter_write };
+       { FILTEROP_ISFD, NULL, apmfilter_detach, apmfilter_write };
 
 static int
 apmkqfilter(struct dev_kqfilter_args *ap)
index 7f9b4f6..fac7ad8 100644 (file)
@@ -842,7 +842,7 @@ ascioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops ascfiltops =
-    { 1, NULL, ascfilter_detach, ascfilter };
+    { FILTEROP_ISFD, NULL, ascfilter_detach, ascfilter };
 
 STATIC int
 asckqfilter(struct dev_kqfilter_args *ap)
index 8a1079b..fc77ca9 100644 (file)
@@ -92,7 +92,8 @@ struct kevent {
 #define NOTE_LOWAT     0x0001                  /* low water mark */
 
 /*
- * data/hint flags for EVFILT_EXCEPT, shared with userspace
+ * data/hint flags for EVFILT_EXCEPT, shared with userspace and with
+ * EVFILT_{READ|WRITE}
  */
 #define NOTE_OOB       0x0002                  /* OOB data on a socket */
 
@@ -148,8 +149,11 @@ MALLOC_DECLARE(M_KQUEUE);
  */
 #define NOTE_SIGNAL    0x08000000
 
+#define FILTEROP_ISFD  0x0001          /* if ident == filedescriptor */
+#define FILTEROP_MPSAFE        0x0002
+
 struct filterops {
-       int     f_isfd;         /* true if ident == filedescriptor */
+       u_short f_flags;
 
        /* f_attach returns 0 on success or valid error code on failure */
        int     (*f_attach)     (struct knote *kn);
index 6be797b..2c35796 100644 (file)
@@ -85,9 +85,9 @@ static void   filt_fifowdetach(struct knote *kn);
 static int     filt_fifowrite(struct knote *kn, long hint);
 
 static struct filterops fiforead_filtops =
-       { 1, NULL, filt_fifordetach, filt_fiforead };
+       { FILTEROP_ISFD, NULL, filt_fifordetach, filt_fiforead };
 static struct filterops fifowrite_filtops =
-       { 1, NULL, filt_fifowdetach, filt_fifowrite };
+       { FILTEROP_ISFD, NULL, filt_fifowdetach, filt_fifowrite };
   
 struct vop_ops fifo_vnode_vops = {
        .vop_default =          vop_defaultop,
index e4efbdc..8283e8c 100644 (file)
@@ -1927,11 +1927,11 @@ ext2_vinit(struct mount *mntp, struct vnode **vpp)
 }
 
 static struct filterops ext2read_filtops = 
-       { 1, NULL, filt_ext2detach, filt_ext2read };
+       { FILTEROP_ISFD, NULL, filt_ext2detach, filt_ext2read };
 static struct filterops ext2write_filtops = 
-       { 1, NULL, filt_ext2detach, filt_ext2write };
+       { FILTEROP_ISFD, NULL, filt_ext2detach, filt_ext2write };
 static struct filterops ext2vnode_filtops = 
-       { 1, NULL, filt_ext2detach, filt_ext2vnode };
+       { FILTEROP_ISFD, NULL, filt_ext2detach, filt_ext2vnode };
 
 /*
  * ext2_kqfilter(struct vnode *a_vp, struct knote *a_kn)
index 9d1dabf..681e5ce 100644 (file)
@@ -3348,11 +3348,11 @@ static int filt_hammerwrite(struct knote *kn, long hint);
 static int filt_hammervnode(struct knote *kn, long hint);
 
 static struct filterops hammerread_filtops =
-       { 1, NULL, filt_hammerdetach, filt_hammerread };
+       { FILTEROP_ISFD, NULL, filt_hammerdetach, filt_hammerread };
 static struct filterops hammerwrite_filtops =
-       { 1, NULL, filt_hammerdetach, filt_hammerwrite };
+       { FILTEROP_ISFD, NULL, filt_hammerdetach, filt_hammerwrite };
 static struct filterops hammervnode_filtops =
-       { 1, NULL, filt_hammerdetach, filt_hammervnode };
+       { FILTEROP_ISFD, NULL, filt_hammerdetach, filt_hammervnode };
 
 static
 int
index cc20531..0640f4a 100644 (file)
@@ -2119,11 +2119,11 @@ ufs_missingop(struct vop_generic_args *ap)
 }
 
 static struct filterops ufsread_filtops = 
-       { 1, NULL, filt_ufsdetach, filt_ufsread };
+       { FILTEROP_ISFD, NULL, filt_ufsdetach, filt_ufsread };
 static struct filterops ufswrite_filtops = 
-       { 1, NULL, filt_ufsdetach, filt_ufswrite };
+       { FILTEROP_ISFD, NULL, filt_ufsdetach, filt_ufswrite };
 static struct filterops ufsvnode_filtops = 
-       { 1, NULL, filt_ufsdetach, filt_ufsvnode };
+       { FILTEROP_ISFD, NULL, filt_ufsdetach, filt_ufsvnode };
 
 /*
  * ufs_kqfilter(struct vnode *a_vp, struct knote *a_kn)