Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 Nov 2018 17:11:48 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r340904 - stable/11/sys/kern
Message-ID:  <201811241711.wAOHBmMD012641@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Sat Nov 24 17:11:47 2018
New Revision: 340904
URL: https://svnweb.freebsd.org/changeset/base/340904

Log:
  MFC r340734:
  Avoid unsynchronized updates to kn_status.

Modified:
  stable/11/sys/kern/kern_event.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/kern/kern_event.c
==============================================================================
--- stable/11/sys/kern/kern_event.c	Sat Nov 24 17:09:35 2018	(r340903)
+++ stable/11/sys/kern/kern_event.c	Sat Nov 24 17:11:47 2018	(r340904)
@@ -1391,6 +1391,8 @@ findkn:
 			kn->kn_kevent.flags &= ~(EV_ADD | EV_DELETE |
 			    EV_ENABLE | EV_DISABLE | EV_FORCEONESHOT);
 			kn->kn_status = KN_INFLUX|KN_DETACHED;
+			if ((kev->flags & EV_DISABLE) != 0)
+				kn->kn_status |= KN_DISABLED;
 
 			error = knote_attach(kn, kq);
 			KQ_UNLOCK(kq);
@@ -1427,6 +1429,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
@@ -1443,19 +1450,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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201811241711.wAOHBmMD012641>