Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Mar 2014 18:09:08 +0000 (UTC)
From:      Jim Harris <jimharris@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r263310 - head/sys/dev/nvme
Message-ID:  <201403181809.s2II98oi074405@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jimharris
Date: Tue Mar 18 18:09:08 2014
New Revision: 263310
URL: http://svnweb.freebsd.org/changeset/base/263310

Log:
  nvme: Close hole where nvd(4) would not be notified of all nvme(4)
  instances if modules loaded during boot.
  
  Sponsored by:	Intel
  MFC after:	3 days

Modified:
  head/sys/dev/nvme/nvme.c
  head/sys/dev/nvme/nvme_ctrlr.c
  head/sys/dev/nvme/nvme_private.h

Modified: head/sys/dev/nvme/nvme.c
==============================================================================
--- head/sys/dev/nvme/nvme.c	Tue Mar 18 17:17:42 2014	(r263309)
+++ head/sys/dev/nvme/nvme.c	Tue Mar 18 18:09:08 2014	(r263310)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (C) 2012-2013 Intel Corporation
+ * Copyright (C) 2012-2014 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -266,39 +266,75 @@ nvme_detach (device_t dev)
 }
 
 static void
-nvme_notify_consumer(struct nvme_consumer *cons)
+nvme_notify(struct nvme_consumer *cons,
+	    struct nvme_controller *ctrlr)
 {
-	device_t		*devlist;
-	struct nvme_controller	*ctrlr;
 	struct nvme_namespace	*ns;
 	void			*ctrlr_cookie;
-	int			dev_idx, ns_idx, devcount;
+	int			cmpset, ns_idx;
+
+	/*
+	 * The consumer may register itself after the nvme devices
+	 *  have registered with the kernel, but before the
+	 *  driver has completed initialization.  In that case,
+	 *  return here, and when initialization completes, the
+	 *  controller will make sure the consumer gets notified.
+	 */
+	if (!ctrlr->is_initialized)
+		return;
+
+	cmpset = atomic_cmpset_32(&ctrlr->notification_sent, 0, 1);
+
+	if (cmpset == 0)
+		return;
+
+	if (cons->ctrlr_fn != NULL)
+		ctrlr_cookie = (*cons->ctrlr_fn)(ctrlr);
+	else
+		ctrlr_cookie = NULL;
+	ctrlr->cons_cookie[cons->id] = ctrlr_cookie;
+	if (ctrlr->is_failed) {
+		if (cons->fail_fn != NULL)
+			(*cons->fail_fn)(ctrlr_cookie);
+		/*
+		 * Do not notify consumers about the namespaces of a
+		 *  failed controller.
+		 */
+		return;
+	}
+	for (ns_idx = 0; ns_idx < ctrlr->cdata.nn; ns_idx++) {
+		ns = &ctrlr->ns[ns_idx];
+		if (cons->ns_fn != NULL)
+			ns->cons_cookie[cons->id] =
+			    (*cons->ns_fn)(ns, ctrlr_cookie);
+	}
+}
+
+void
+nvme_notify_new_controller(struct nvme_controller *ctrlr)
+{
+	int i;
+
+	for (i = 0; i < NVME_MAX_CONSUMERS; i++) {
+		if (nvme_consumer[i].id != INVALID_CONSUMER_ID) {
+			nvme_notify(&nvme_consumer[i], ctrlr);
+		}
+	}
+}
+
+static void
+nvme_notify_new_consumer(struct nvme_consumer *cons)
+{
+	device_t		*devlist;
+	struct nvme_controller	*ctrlr;
+	int			dev_idx, devcount;
 
 	if (devclass_get_devices(nvme_devclass, &devlist, &devcount))
 		return;
 
 	for (dev_idx = 0; dev_idx < devcount; dev_idx++) {
 		ctrlr = DEVICE2SOFTC(devlist[dev_idx]);
-		if (cons->ctrlr_fn != NULL)
-			ctrlr_cookie = (*cons->ctrlr_fn)(ctrlr);
-		else
-			ctrlr_cookie = NULL;
-		ctrlr->cons_cookie[cons->id] = ctrlr_cookie;
-		if (ctrlr->is_failed) {
-			if (cons->fail_fn != NULL)
-				(*cons->fail_fn)(ctrlr_cookie);
-			/*
-			 * Do not notify consumers about the namespaces of a
-			 *  failed controller.
-			 */
-			continue;
-		}
-		for (ns_idx = 0; ns_idx < ctrlr->cdata.nn; ns_idx++) {
-			ns = &ctrlr->ns[ns_idx];
-			if (cons->ns_fn != NULL)
-				ns->cons_cookie[cons->id] =
-				    (*cons->ns_fn)(ns, ctrlr_cookie);
-		}
+		nvme_notify(cons, ctrlr);
 	}
 
 	free(devlist, M_TEMP);
@@ -353,7 +389,7 @@ nvme_register_consumer(nvme_cons_ns_fn_t
 			nvme_consumer[i].async_fn = async_fn;
 			nvme_consumer[i].fail_fn = fail_fn;
 
-			nvme_notify_consumer(&nvme_consumer[i]);
+			nvme_notify_new_consumer(&nvme_consumer[i]);
 			return (&nvme_consumer[i]);
 		}
 

Modified: head/sys/dev/nvme/nvme_ctrlr.c
==============================================================================
--- head/sys/dev/nvme/nvme_ctrlr.c	Tue Mar 18 17:17:42 2014	(r263309)
+++ head/sys/dev/nvme/nvme_ctrlr.c	Tue Mar 18 18:09:08 2014	(r263310)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (C) 2012-2013 Intel Corporation
+ * Copyright (C) 2012-2014 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -851,6 +851,9 @@ nvme_ctrlr_start_config_hook(void *arg)
 
 	nvme_ctrlr_start(ctrlr);
 	config_intrhook_disestablish(&ctrlr->config_hook);
+
+	ctrlr->is_initialized = 1;
+	nvme_notify_new_controller(ctrlr);
 }
 
 static void
@@ -1174,6 +1177,8 @@ intx:
 	taskqueue_start_threads(&ctrlr->taskqueue, 1, PI_DISK, "nvme taskq");
 
 	ctrlr->is_resetting = 0;
+	ctrlr->is_initialized = 0;
+	ctrlr->notification_sent = 0;
 	TASK_INIT(&ctrlr->reset_task, 0, nvme_ctrlr_reset_task, ctrlr);
 
 	TASK_INIT(&ctrlr->fail_req_task, 0, nvme_ctrlr_fail_req_task, ctrlr);

Modified: head/sys/dev/nvme/nvme_private.h
==============================================================================
--- head/sys/dev/nvme/nvme_private.h	Tue Mar 18 17:17:42 2014	(r263309)
+++ head/sys/dev/nvme/nvme_private.h	Tue Mar 18 18:09:08 2014	(r263310)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (C) 2012-2013 Intel Corporation
+ * Copyright (C) 2012-2014 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -330,7 +330,9 @@ struct nvme_controller {
 
 	void				*cons_cookie[NVME_MAX_CONSUMERS];
 
-	uint32_t		is_resetting;
+	uint32_t			is_resetting;
+	uint32_t			is_initialized;
+	uint32_t			notification_sent;
 
 	boolean_t			is_failed;
 	STAILQ_HEAD(, nvme_request)	fail_req;
@@ -556,5 +558,6 @@ void	nvme_notify_async_consumers(struct 
 				    uint32_t log_page_id, void *log_page_buffer,
 				    uint32_t log_page_size);
 void	nvme_notify_fail_consumers(struct nvme_controller *ctrlr);
+void	nvme_notify_new_controller(struct nvme_controller *ctrlr);
 
 #endif /* __NVME_PRIVATE_H__ */



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