diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-09 20:46:54 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-09 20:46:54 +0300 |
commit | bd799eb63db4c61a5f2dc941672391fbca5bcab4 (patch) | |
tree | 6837515d14beac117723ead93fdf7114bacbcf11 /tools | |
parent | 6ec067e3a4492569699676d75a21fcee22fefc5b (diff) | |
parent | b5fd2e00a60248902315fb32210550ac3cb9f44c (diff) | |
download | linux-bd799eb63db4c61a5f2dc941672391fbca5bcab4.tar.xz |
Merge tag 'libnvdimm-fixes-4.20-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm fixes from Dan Williams:
"A regression fix for the Address Range Scrub implementation, yes
another one, and support for platforms that misalign persistent memory
relative to the Linux memory hotplug section constraint. Longer term,
support for sub-section memory hotplug would alleviate alignment
waste, but until then this hack allows a 'struct page' memmap to be
established for these misaligned memory regions.
These have all appeared in a -next release, and thanks to Patrick for
reporting and testing the alignment padding fix.
Summary:
- Unless and until the core mm handles memory hotplug units smaller
than a section (128M), persistent memory namespaces must be padded
to section alignment.
The libnvdimm core already handled section collision with "System
RAM", but some configurations overlap independent "Persistent
Memory" ranges within a section, so additional padding injection is
added for that case.
- The recent reworks of the ARS (address range scrub) state machine
to reduce the number of state flags inadvertantly missed a
conversion of acpi_nfit_ars_rescan() call sites. Fix the regression
whereby user-requested ARS results in a "short" scrub rather than a
"long" scrub.
- Fixup the unit tests to handle / test the 128M section alignment of
mocked test resources.
* tag 'libnvdimm-fixes-4.20-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
acpi/nfit: Fix user-initiated ARS to be "ARS-long" rather than "ARS-short"
libnvdimm, pfn: Pad pfn namespaces relative to other regions
tools/testing/nvdimm: Align test resources to 128M
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/nvdimm/test/nfit.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index 01ec04bf91b5..6c16ac36d482 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c @@ -15,6 +15,7 @@ #include <linux/dma-mapping.h> #include <linux/workqueue.h> #include <linux/libnvdimm.h> +#include <linux/genalloc.h> #include <linux/vmalloc.h> #include <linux/device.h> #include <linux/module.h> @@ -215,6 +216,8 @@ struct nfit_test { static struct workqueue_struct *nfit_wq; +static struct gen_pool *nfit_pool; + static struct nfit_test *to_nfit_test(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -1132,6 +1135,9 @@ static void release_nfit_res(void *data) list_del(&nfit_res->list); spin_unlock(&nfit_test_lock); + if (resource_size(&nfit_res->res) >= DIMM_SIZE) + gen_pool_free(nfit_pool, nfit_res->res.start, + resource_size(&nfit_res->res)); vfree(nfit_res->buf); kfree(nfit_res); } @@ -1144,7 +1150,7 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma, GFP_KERNEL); int rc; - if (!buf || !nfit_res) + if (!buf || !nfit_res || !*dma) goto err; rc = devm_add_action(dev, release_nfit_res, nfit_res); if (rc) @@ -1164,6 +1170,8 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma, return nfit_res->buf; err: + if (*dma && size >= DIMM_SIZE) + gen_pool_free(nfit_pool, *dma, size); if (buf) vfree(buf); kfree(nfit_res); @@ -1172,9 +1180,16 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma, static void *test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma) { + struct genpool_data_align data = { + .align = SZ_128M, + }; void *buf = vmalloc(size); - *dma = (unsigned long) buf; + if (size >= DIMM_SIZE) + *dma = gen_pool_alloc_algo(nfit_pool, size, + gen_pool_first_fit_align, &data); + else + *dma = (unsigned long) buf; return __test_alloc(t, size, dma, buf); } @@ -2839,6 +2854,17 @@ static __init int nfit_test_init(void) goto err_register; } + nfit_pool = gen_pool_create(ilog2(SZ_4M), NUMA_NO_NODE); + if (!nfit_pool) { + rc = -ENOMEM; + goto err_register; + } + + if (gen_pool_add(nfit_pool, SZ_4G, SZ_4G, NUMA_NO_NODE)) { + rc = -ENOMEM; + goto err_register; + } + for (i = 0; i < NUM_NFITS; i++) { struct nfit_test *nfit_test; struct platform_device *pdev; @@ -2894,6 +2920,9 @@ static __init int nfit_test_init(void) return 0; err_register: + if (nfit_pool) + gen_pool_destroy(nfit_pool); + destroy_workqueue(nfit_wq); for (i = 0; i < NUM_NFITS; i++) if (instances[i]) @@ -2917,6 +2946,8 @@ static __exit void nfit_test_exit(void) platform_driver_unregister(&nfit_test_driver); nfit_test_teardown(); + gen_pool_destroy(nfit_pool); + for (i = 0; i < NUM_NFITS; i++) put_device(&instances[i]->pdev.dev); class_destroy(nfit_test_dimm); |