From owner-svn-src-all@freebsd.org Thu Jan 31 22:43:21 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id BC0E714BA83D; Thu, 31 Jan 2019 22:43:21 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 537327705A; Thu, 31 Jan 2019 22:43:21 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 419F9E2D3; Thu, 31 Jan 2019 22:43:21 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x0VMhLpj089929; Thu, 31 Jan 2019 22:43:21 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x0VMhK9v089926; Thu, 31 Jan 2019 22:43:20 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201901312243.x0VMhK9v089926@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Thu, 31 Jan 2019 22:43:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r343628 - head/sys/dev/nvdimm X-SVN-Group: head X-SVN-Commit-Author: kib X-SVN-Commit-Paths: head/sys/dev/nvdimm X-SVN-Commit-Revision: 343628 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 537327705A X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.96 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.998,0]; NEURAL_HAM_SHORT(-0.96)[-0.961,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-0.999,0] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 31 Jan 2019 22:43:22 -0000 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 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__ */