svn commit: r343628 - head/sys/dev/nvdimm

Konstantin Belousov kib at FreeBSD.org
Thu Jan 31 22:43:22 UTC 2019


Author: kib
Date: Thu Jan 31 22:43:20 2019
New Revision: 343628
URL: https://svnweb.freebsd.org/changeset/base/343628

Log:
  nvdimm: enumerate NVDIMM SPA ranges from the root device
  
  Move the enumeration of NVDIMM SPA ranges from the spa GEOM class
  initializer into the NVDIMM root device. This will be necessary for a
  later change where NVDIMM namespaces require NVDIMM device enumeration
  to be reliably ordered before SPA enumeration.
  
  Submitted by:	D Scott Phillips <d.scott.phillips at intel.com>
  Sponsored by:	Intel Corporation
  MFC after:	1 week
  Differential revision:	https://reviews.freebsd.org/D18734

Modified:
  head/sys/dev/nvdimm/nvdimm.c
  head/sys/dev/nvdimm/nvdimm_spa.c
  head/sys/dev/nvdimm/nvdimm_var.h

Modified: head/sys/dev/nvdimm/nvdimm.c
==============================================================================
--- head/sys/dev/nvdimm/nvdimm.c	Thu Jan 31 22:37:28 2019	(r343627)
+++ head/sys/dev/nvdimm/nvdimm.c	Thu Jan 31 22:43:20 2019	(r343628)
@@ -227,6 +227,31 @@ nvdimm_resume(device_t dev)
 	return (0);
 }
 
+static int
+nvdimm_root_create_spa(void *nfitsubtbl, void *arg)
+{
+	enum SPA_mapping_type spa_type;
+	ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr;
+	struct SPA_mapping *spa;
+	struct nvdimm_root_dev *dev;
+	int error;
+
+	nfitaddr = nfitsubtbl;
+	dev = arg;
+	spa_type = nvdimm_spa_type_from_uuid(
+	    (struct uuid *)nfitaddr->RangeGuid);
+	if (spa_type == SPA_TYPE_UNKNOWN)
+		return (0);
+	spa = malloc(sizeof(struct SPA_mapping), M_NVDIMM, M_WAITOK | M_ZERO);
+	error = nvdimm_spa_init(spa, nfitaddr, spa_type);
+	if (error != 0) {
+		nvdimm_spa_fini(spa);
+		free(spa, M_NVDIMM);
+	}
+	SLIST_INSERT_HEAD(&dev->spas, spa, link);
+	return (0);
+}
+
 static ACPI_STATUS
 nvdimm_root_create_dev(ACPI_HANDLE handle, UINT32 nesting_level, void *context,
     void **return_value)
@@ -276,6 +301,7 @@ nvdimm_root_attach(device_t dev)
 {
 	ACPI_HANDLE handle;
 	ACPI_STATUS status;
+	ACPI_TABLE_NFIT *nfitbl;
 	int error;
 
 	handle = acpi_get_handle(dev);
@@ -284,15 +310,33 @@ nvdimm_root_attach(device_t dev)
 	if (ACPI_FAILURE(status))
 		device_printf(dev, "failed adding children\n");
 	error = bus_generic_attach(dev);
+	if (error != 0)
+		return (error);
+	status = AcpiGetTable(ACPI_SIG_NFIT, 1, (ACPI_TABLE_HEADER **)&nfitbl);
+	if (ACPI_FAILURE(status)) {
+		device_printf(dev, "cannot get NFIT\n");
+		return (ENXIO);
+	}
+	error = nvdimm_iterate_nfit(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS,
+	    nvdimm_root_create_spa, device_get_softc(dev));
+	AcpiPutTable(&nfitbl->Header);
 	return (error);
 }
 
 static int
 nvdimm_root_detach(device_t dev)
 {
+	struct nvdimm_root_dev *root;
+	struct SPA_mapping *spa, *next;
 	device_t *children;
 	int i, error, num_children;
 
+	root = device_get_softc(dev);
+	SLIST_FOREACH_SAFE(spa, &root->spas, link, next) {
+		nvdimm_spa_fini(spa);
+		SLIST_REMOVE_HEAD(&root->spas, link);
+		free(spa, M_NVDIMM);
+	}
 	error = bus_generic_detach(dev);
 	if (error != 0)
 		return (error);
@@ -356,6 +400,7 @@ static device_method_t nvdimm_root_methods[] = {
 static driver_t	nvdimm_root_driver = {
 	"nvdimm_root",
 	nvdimm_root_methods,
+	sizeof(struct nvdimm_root_dev),
 };
 
 DRIVER_MODULE(nvdimm_root, acpi, nvdimm_root_driver, nvdimm_root_devclass, NULL,

Modified: head/sys/dev/nvdimm/nvdimm_spa.c
==============================================================================
--- head/sys/dev/nvdimm/nvdimm_spa.c	Thu Jan 31 22:37:28 2019	(r343627)
+++ head/sys/dev/nvdimm/nvdimm_spa.c	Thu Jan 31 22:43:20 2019	(r343628)
@@ -82,19 +82,6 @@ __FBSDID("$FreeBSD$");
 #define UUID_INITIALIZER_PERSISTENT_VIRTUAL_CD \
     {0x08018188,0x42cd,0xbb48,0x10,0x0f,{0x53,0x87,0xd5,0x3d,0xed,0x3d}}
 
-struct SPA_mapping *spa_mappings;
-int spa_mappings_cnt;
-
-static int
-nvdimm_spa_count(void *nfitsubtbl __unused, void *arg)
-{
-	int *cnt;
-
-	cnt = arg;
-	(*cnt)++;
-	return (0);
-}
-
 static struct nvdimm_SPA_uuid_list_elm {
 	const char		*u_name;
 	struct uuid		u_id;
@@ -419,22 +406,17 @@ nvdimm_spa_g_access(struct g_provider *pp, int r, int 
 	return (0);
 }
 
-static g_init_t nvdimm_spa_g_init;
-static g_fini_t nvdimm_spa_g_fini;
-
 struct g_class nvdimm_spa_g_class = {
 	.name =		"SPA",
 	.version =	G_VERSION,
 	.start =	nvdimm_spa_g_start,
 	.access =	nvdimm_spa_g_access,
-	.init =		nvdimm_spa_g_init,
-	.fini =		nvdimm_spa_g_fini,
 };
 DECLARE_GEOM_CLASS(nvdimm_spa_g_class, g_spa);
 
-static int
-nvdimm_spa_init_one(struct SPA_mapping *spa, ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr,
-    int spa_type)
+int
+nvdimm_spa_init(struct SPA_mapping *spa, ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr,
+    enum SPA_mapping_type spa_type)
 {
 	struct make_dev_args mda;
 	struct sglist *spa_sg;
@@ -512,7 +494,7 @@ nvdimm_spa_init_one(struct SPA_mapping *spa, ACPI_NFIT
 		if (error1 == 0)
 			error1 = error;
 	} else {
-		g_topology_assert();
+		g_topology_lock();
 		spa->spa_g = g_new_geomf(&nvdimm_spa_g_class, "spa%d",
 		    spa->spa_nfit_idx);
 		spa->spa_g->softc = spa;
@@ -526,12 +508,13 @@ nvdimm_spa_init_one(struct SPA_mapping *spa, ACPI_NFIT
 		spa->spa_g_devstat = devstat_new_entry("spa", spa->spa_nfit_idx,
 		    DEV_BSIZE, DEVSTAT_ALL_SUPPORTED, DEVSTAT_TYPE_DIRECT,
 		    DEVSTAT_PRIORITY_MAX);
+		g_topology_unlock();
 	}
 	return (error1);
 }
 
-static void
-nvdimm_spa_fini_one(struct SPA_mapping *spa)
+void
+nvdimm_spa_fini(struct SPA_mapping *spa)
 {
 
 	mtx_lock(&spa->spa_g_mtx);
@@ -562,88 +545,4 @@ nvdimm_spa_fini_one(struct SPA_mapping *spa)
 	}
 	mtx_destroy(&spa->spa_g_mtx);
 	mtx_destroy(&spa->spa_g_stat_mtx);
-}
-
-static int
-nvdimm_spa_parse(void *nfitsubtbl, void *arg)
-{
-	ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr;
-	struct SPA_mapping *spa;
-	enum SPA_mapping_type spa_type;
-	int error, *i;
-
-	i = arg;
-	spa = &spa_mappings[(*i)++];
-	nfitaddr = nfitsubtbl;
-	spa_type = nvdimm_spa_type_from_uuid(
-	    (struct uuid *)&nfitaddr->RangeGuid);
-	if (spa_type == SPA_TYPE_UNKNOWN) {
-		printf("Unknown SPA UUID %d ", nfitaddr->RangeIndex);
-		printf_uuid((struct uuid *)&nfitaddr->RangeGuid);
-		printf("\n");
-		return (0);
-	}
-	error = nvdimm_spa_init_one(spa, nfitaddr, spa_type);
-	if (error != 0)
-		nvdimm_spa_fini_one(spa);
-	return (0);
-}
-
-static int
-nvdimm_spa_init1(ACPI_TABLE_NFIT *nfitbl)
-{
-	int error, i;
-
-	error = nvdimm_iterate_nfit(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS,
-	    nvdimm_spa_count, &spa_mappings_cnt);
-	if (error != 0)
-		return (error);
-	spa_mappings = malloc(sizeof(struct SPA_mapping) * spa_mappings_cnt,
-	    M_NVDIMM, M_WAITOK | M_ZERO);
-	i = 0;
-	error = nvdimm_iterate_nfit(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS,
-	    nvdimm_spa_parse, &i);
-	if (error != 0) {
-		free(spa_mappings, M_NVDIMM);
-		spa_mappings = NULL;
-		return (error);
-	}
-	return (0);
-}
-
-static void
-nvdimm_spa_g_init(struct g_class *mp __unused)
-{
-	ACPI_TABLE_NFIT *nfitbl;
-	ACPI_STATUS status;
-	int error;
-
-	spa_mappings_cnt = 0;
-	spa_mappings = NULL;
-	if (acpi_disabled("nvdimm"))
-		return;
-	status = AcpiGetTable(ACPI_SIG_NFIT, 1, (ACPI_TABLE_HEADER **)&nfitbl);
-	if (ACPI_FAILURE(status)) {
-		if (bootverbose)
-			printf("nvdimm_spa_g_init: cannot find NFIT\n");
-		return;
-	}
-	error = nvdimm_spa_init1(nfitbl);
-	if (error != 0)
-		printf("nvdimm_spa_g_init: error %d\n", error);
-	AcpiPutTable(&nfitbl->Header);
-}
-
-static void
-nvdimm_spa_g_fini(struct g_class *mp __unused)
-{
-	int i;
-
-	if (spa_mappings == NULL)
-		return;
-	for (i = 0; i < spa_mappings_cnt; i++)
-		nvdimm_spa_fini_one(&spa_mappings[i]);
-	free(spa_mappings, M_NVDIMM);
-	spa_mappings = NULL;
-	spa_mappings_cnt = 0;
 }

Modified: head/sys/dev/nvdimm/nvdimm_var.h
==============================================================================
--- head/sys/dev/nvdimm/nvdimm_var.h	Thu Jan 31 22:37:28 2019	(r343627)
+++ head/sys/dev/nvdimm/nvdimm_var.h	Thu Jan 31 22:43:20 2019	(r343628)
@@ -44,6 +44,10 @@ __BUS_ACCESSOR(nvdimm_root, acpi_handle, NVDIMM_ROOT, 
 __BUS_ACCESSOR(nvdimm_root, device_handle, NVDIMM_ROOT, DEVICE_HANDLE,
     nfit_handle_t)
 
+struct nvdimm_root_dev {
+	SLIST_HEAD(, SPA_mapping) spas;
+};
+
 struct nvdimm_dev {
 	device_t	nv_dev;
 	nfit_handle_t	nv_handle;
@@ -64,6 +68,7 @@ enum SPA_mapping_type {
 };
 
 struct SPA_mapping {
+	SLIST_ENTRY(SPA_mapping) link;
 	enum SPA_mapping_type	spa_type;
 	int			spa_domain;
 	int			spa_nfit_idx;
@@ -84,14 +89,14 @@ struct SPA_mapping {
 	bool			spa_g_proc_exiting;
 };
 
-extern struct SPA_mapping *spa_mappings;
-extern int spa_mappings_cnt;
-
 MALLOC_DECLARE(M_NVDIMM);
 
 enum SPA_mapping_type nvdimm_spa_type_from_uuid(struct uuid *);
 struct nvdimm_dev *nvdimm_find_by_handle(nfit_handle_t nv_handle);
 int nvdimm_iterate_nfit(ACPI_TABLE_NFIT *nfitbl, enum AcpiNfitType type,
     int (*cb)(void *, void *), void *arg);
+int nvdimm_spa_init(struct SPA_mapping *spa, ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr,
+    enum SPA_mapping_type spa_type);
+void nvdimm_spa_fini(struct SPA_mapping *spa);
 
 #endif		/* __DEV_NVDIMM_VAR_H__ */


More information about the svn-src-all mailing list