Author: markj
Date: Mon Nov 26 15:46:46 2018
New Revision: 340977
URL: https://svnweb.freebsd.org/changeset/base/340977

Log:
  MFstable/12 r340903:
  Avoid unsynchronized updates to kn_status.
  
  Approved by:  re (gjb)

Modified:
  releng/12.0/sys/kern/kern_event.c
Directory Properties:
  releng/12.0/   (props changed)

Modified: releng/12.0/sys/kern/kern_event.c
==============================================================================
--- releng/12.0/sys/kern/kern_event.c   Mon Nov 26 15:33:55 2018        
(r340976)
+++ releng/12.0/sys/kern/kern_event.c   Mon Nov 26 15:46:46 2018        
(r340977)
@@ -1535,6 +1535,8 @@ findkn:
                        kn->kn_kevent.flags &= ~(EV_ADD | EV_DELETE |
                            EV_ENABLE | EV_DISABLE | EV_FORCEONESHOT);
                        kn->kn_status = KN_DETACHED;
+                       if ((kev->flags & EV_DISABLE) != 0)
+                               kn->kn_status |= KN_DISABLED;
                        kn_enter_flux(kn);
 
                        error = knote_attach(kn, kq);
@@ -1570,6 +1572,11 @@ findkn:
                KNOTE_ACTIVATE(kn, 1);
        }
 
+       if ((kev->flags & EV_ENABLE) != 0)
+               kn->kn_status &= ~KN_DISABLED;
+       else if ((kev->flags & EV_DISABLE) != 0)
+               kn->kn_status |= KN_DISABLED;
+
        /*
         * The user may change some filter values after the initial EV_ADD,
         * but doing so will not reset any filter which has already been
@@ -1587,19 +1594,17 @@ findkn:
                kn->kn_sdata = kev->data;
        }
 
+done_ev_add:
        /*
         * We can get here with kn->kn_knlist == NULL.  This can happen when
         * the initial attach event decides that the event is "completed" 
-        * already.  i.e. filt_procattach is called on a zombie process.  It
-        * will call filt_proc which will remove it from the list, and NULL
+        * already, e.g., filt_procattach() is called on a zombie process.  It
+        * will call filt_proc() which will remove it from the list, and NULL
         * kn_knlist.
+        *
+        * KN_DISABLED will be stable while the knote is in flux, so the
+        * unlocked read will not race with an update.
         */
-done_ev_add:
-       if ((kev->flags & EV_ENABLE) != 0)
-               kn->kn_status &= ~KN_DISABLED;
-       else if ((kev->flags & EV_DISABLE) != 0)
-               kn->kn_status |= KN_DISABLED;
-
        if ((kn->kn_status & KN_DISABLED) == 0)
                event = kn->kn_fop->f_event(kn, 0);
        else
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to