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