svn commit: r324415 - in head/sys: kern sys

Ian Lepore ian at FreeBSD.org
Sun Oct 8 17:33:51 UTC 2017


Author: ian
Date: Sun Oct  8 17:33:49 2017
New Revision: 324415
URL: https://svnweb.freebsd.org/changeset/base/324415

Log:
  Add eventhandler notifications for newbus device attach/detach.
  
  The detach case is slightly complicated by the fact that some in-kernel
  consumers may want to know before a device detaches (so they can release
  related resources, stop using the device, etc), but the detach can fail. So
  there are pre- and post-detach notifications for those consumers who need to
  handle all cases.
  
  A couple salient comments from the review, they amount to some helpful
  documentation about these events, but there's currently no good place for
  such documentation...
  
  Note that in the current newbus locking model, DETACH_BEGIN and
  DETACH_COMPLETE/FAILED sequence of event handler invocation might interweave
  with other attach/detach events arbitrarily. The handlers should be prepared
  for such situations.
  
  Also should note that detach may be called after the parent bus knows the
  hardware has left the building. In-kernel consumers have to be prepared to
  cope with this race.
  
  Differential Revision:	https://reviews.freebsd.org/D12557

Modified:
  head/sys/kern/subr_bus.c
  head/sys/sys/eventhandler.h

Modified: head/sys/kern/subr_bus.c
==============================================================================
--- head/sys/kern/subr_bus.c	Sun Oct  8 17:29:43 2017	(r324414)
+++ head/sys/kern/subr_bus.c	Sun Oct  8 17:33:49 2017	(r324415)
@@ -2936,6 +2936,7 @@ device_attach(device_t dev)
 	else
 		dev->state = DS_ATTACHED;
 	dev->flags &= ~DF_DONENOMATCH;
+	EVENTHANDLER_INVOKE(device_attach, dev);
 	devadded(dev);
 	return (0);
 }
@@ -2969,8 +2970,13 @@ device_detach(device_t dev)
 	if (dev->state != DS_ATTACHED)
 		return (0);
 
-	if ((error = DEVICE_DETACH(dev)) != 0)
+	EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_BEGIN);
+	if ((error = DEVICE_DETACH(dev)) != 0) {
+		EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_FAILED);
 		return (error);
+	} else {
+		EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_COMPLETE);
+	}
 	devremoved(dev);
 	if (!device_is_quiet(dev))
 		device_printf(dev, "detached\n");

Modified: head/sys/sys/eventhandler.h
==============================================================================
--- head/sys/sys/eventhandler.h	Sun Oct  8 17:29:43 2017	(r324414)
+++ head/sys/sys/eventhandler.h	Sun Oct  8 17:33:49 2017	(r324415)
@@ -293,4 +293,15 @@ typedef void (*swapoff_fn)(void *, struct swdevt *);
 EVENTHANDLER_DECLARE(swapon, swapon_fn);
 EVENTHANDLER_DECLARE(swapoff, swapoff_fn);
 
+/* newbus device events */
+enum evhdev_detach {
+	EVHDEV_DETACH_BEGIN,    /* Before detach() is called */
+	EVHDEV_DETACH_COMPLETE, /* After detach() returns 0 */
+	EVHDEV_DETACH_FAILED    /* After detach() returns err */
+};
+typedef void (*device_attach_fn)(void *, device_t);
+typedef void (*device_detach_fn)(void *, device_t, enum evhdev_detach);
+EVENTHANDLER_DECLARE(device_attach, device_attach_fn);
+EVENTHANDLER_DECLARE(device_detach, device_detach_fn);
+
 #endif /* _SYS_EVENTHANDLER_H_ */


More information about the svn-src-head mailing list